package com.foton.bpc.all.remoting.netty.handler;

import com.foton.bpc.all.remoting.netty.codec.Codec;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @Author RenPu
 * @Date 2023/6/5 16:57
 * @Version 1.0
 * @Description: 编解码处理器：
 *              例如：1：解决BpcInvacation请求对象已经被序列化得二进制数据，进行反序列化进行解码，封装到java 对象中
 *                   2：解决Reponse对象，进行转为为序列化二进制数据，便于在网络传输给客户端进行接收
 **/

@Slf4j
public class NettyCodecHandler extends ChannelDuplexHandler {

    /**
     * 编解码器
     */
    private Codec codec;

    public NettyCodecHandler(Codec codec) {
        this.codec = codec;
    }
    /**
     *
     *  byte[] --> java object
     * 入栈方法
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        log.info("NettyCodecHandler ：：：编解码  CODEC：：：内容为：："+msg);

        //1：从buffer获取字节数据
        ByteBuf byteBuf=(ByteBuf)msg;
        //2：使用编解码器，进行解码封装为java object
        byte[] data=new byte[byteBuf.readableBytes()];
         byteBuf.readBytes(data);
        List<Object> decode = codec.decode(data);
        //3：交由下一个handler进行处理
        for (Object obj : decode) {
            ctx.fireChannelRead(obj);
        }
        System.out.println("内容为：："+msg);
    }


    /**
     * java object ---> byte[]
     * 出栈方法
     * @param ctx
     * @param msg
     * @param promise
     * @throws Exception
     */
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

       byte[] result= codec.encode(msg);

       //使用netty中的bytebuf对象进行数据传输,否则是不能正常传输到netty中的。 Unpooled.wrappedBuffer(result);

        super.write(ctx, Unpooled.wrappedBuffer(result), promise);
    }
}
